using dnAnalytics.LinearAlgebra;
using NUnit.Framework;

namespace dnAnalytics.UnitTests.LinearAlgebra
{
    public class SparseMatrixTest : AbstractMatrixTest
    {
        public override Matrix GetMatrix(int order)
        {
            return MatrixBuilder.CreateMatrix(order, MatrixType.Sparse);
        }

        public override Matrix GetMatrix(int m, int n)
        {
            return MatrixBuilder.CreateMatrix(m, n, MatrixType.Sparse);
        }

        public override Matrix GetMatrix(double[,] data)
        {
            int rows = data.GetLength(0);
            int cols = data.GetLength(1);
            Matrix ret = MatrixBuilder.CreateMatrix(rows, cols, MatrixType.Sparse);
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    ret[i, j] = data[i, j];
                }
            }

            return ret;
        }

        public override Vector GetVector(int size)
        {
            return VectorBuilder.CreateVector(size, VectorType.Sparse);
        }

        public override Vector GetVector(double[] source)
        {
            return VectorBuilder.CreateVector(source, VectorType.Sparse);
        }
    }

    [TestFixture]
    [Category("Managed")]
    [Category("Sparse")]
    public class ManagedSparseMatrixTest : SparseMatrixTest
    {
        static ManagedSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = false;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Mkl")]
    [Category("Sparse")]
    public class MklSparseMatrixTest : SparseMatrixTest
    {
        static MklSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Mkl;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Mkl;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Acml")]
    [Category("Sparse")]
    public class AcmlSparseMatrixTest : SparseMatrixTest
    {
        static AcmlSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Acml;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }
    
    [TestFixture]
    [Category("Native")]
    [Category("Atlas")]
    [Category("Sparse")]
    public class AtlasClapackSparseMatrixTest : SparseMatrixTest
    {
        static AtlasClapackSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Atlas;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Clapack;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Managed")]
    [Category("Sparse")]
    public class ManagedDenseSparseMatrixTest : SparseMatrixTest
    {
        static ManagedDenseSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = false;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Mkl")]
    [Category("Sparse")]
    public class MklDenseSparseMatrixTest : SparseMatrixTest
    {
        static MklDenseSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Mkl;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Mkl;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Acml")]
    [Category("Sparse")]
    public class AcmlDenseSparseMatrixTest : SparseMatrixTest
    {
        static AcmlDenseSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Acml;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }
   
    [TestFixture]
    [Category("Native")]
    [Category("Atlas")]
    [Category("Sparse")]
    public class AtlasClapackDenseSparseMatrixTest : SparseMatrixTest
    {
        static AtlasClapackDenseSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Atlas;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Clapack;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("AcmlIFort")]
    [Category("Dense")]
    public class AcmlIFortSparseMatrixTest : DenseMatrixTest
    {
        static AcmlIFortSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.AcmlIFort;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("AcmlIFort")]
    [Category("Dense")]
    public class AcmlIFortDenseSparseMatrixTest : DenseMatrixTest
    {
        static AcmlIFortDenseSparseMatrixTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.AcmlIFort;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }
}